using System;
using System.Linq;
using UnityEngine;
using LS.Digitize;

namespace LS.Digitize
{
    public sealed class Matrix4x4Serializer: CompoundSerializer<Matrix4x4>
    {
        public Matrix4x4Serializer() : base(typeof(Matrix4x4),typeof(Vector4))
        {
            
        }
        
        public override void WriteData(IWriter writer, Matrix4x4 obj)
        {
            ISerializer subSerializer = SubSerializer;
            using (writer.WriteObjectScope())
            {
                if (subSerializer is CompoundSerializer<Vector4> ps)
                {
                    using (writer.WritePropertyScope("c0"))
                        ps.WriteData(writer, obj.GetColumn(0));
                    
                    using (writer.WritePropertyScope("c1"))
                        ps.WriteData(writer, obj.GetColumn(1));
                    
                    using (writer.WritePropertyScope("c2"))
                        ps.WriteData(writer, obj.GetColumn(2));
                    
                    using (writer.WritePropertyScope("c3"))
                        ps.WriteData(writer, obj.GetColumn(3));
                }
                else
                {
                    using (writer.WritePropertyScope("c0"))
                        subSerializer.Write(writer, obj.GetColumn(0));
                    
                    using (writer.WritePropertyScope("c1"))
                        subSerializer.Write(writer, obj.GetColumn(1));
                    
                    using (writer.WritePropertyScope("c2"))
                        subSerializer.Write(writer, obj.GetColumn(2));
                    
                    using (writer.WritePropertyScope("c3"))
                        subSerializer.Write(writer, obj.GetColumn(3));
                }
            }
        }

        public override Matrix4x4 ReadData(IReader reader)
        {
            ISerializer subSerializer = SubSerializer;
            Matrix4x4 target = new Matrix4x4();
            using (var objScope = reader.ReadObjectScope())
            {
                string propertyName = null;
                if (subSerializer is PrimitiveSerializer<Vector4> ps)
                {
                    propertyName = reader.ReadPropertyName();
                    Vector4 c0 = ps.ReadData(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c1 = ps.ReadData(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c2 = ps.ReadData(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c3 = ps.ReadData(reader);
                    target.SetColumn(0, c0);
                    target.SetColumn(1, c1);
                    target.SetColumn(2, c2);
                    target.SetColumn(3, c3);
                }
                else
                {
                    propertyName = reader.ReadPropertyName();
                    Vector4 c0 = (Vector4)subSerializer.Read(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c1 = (Vector4)subSerializer.Read(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c2 = (Vector4)subSerializer.Read(reader);
                    propertyName = reader.ReadPropertyName();
                    Vector4 c3 = (Vector4)subSerializer.Read(reader);
                    target.SetColumn(0, c0);
                    target.SetColumn(1, c1);
                    target.SetColumn(2, c2);
                    target.SetColumn(3, c3);
                }
            }

            return target;
        }
        
        public override void ReadInto(IReader reader, ref Matrix4x4 obj)
        {
            obj = ReadData(reader);
        }
    }
}